import { Text, TextProps, View } from '@tarojs/components';
import theme from '@/theme';
import { ComponentProps, useEffect, useMemo, useState } from 'react';
import './index.scss';
import classNames from 'classnames';
import { Column, Grid, Icon } from 'pd-taro-ui';
import { pxTransform } from '@tarojs/taro';
import dayjs, { Dayjs } from 'dayjs';
import { isInTimeRange } from './utils';
import CalendarItem from './CalendarItem';
import type { CalendarRenderItem } from './type';
import YearView from './YearView';
import MonthView from './MonthView';
import { useReactive } from 'ahooks';

export interface CalendarProps {
  placeholder?: string;
  /** day单选， range日期范围(start,end) ,  默认day */
  mode?: 'day' | 'range';
  value?: string | string[];
  onChange?: (value: CalendarProps['value']) => any;
  onBlur?: any;
  staticed?: boolean;
  disabled?: boolean;
  clearable?: boolean;
  className?: string;
  minDate?: string;
  maxDate?: string;
  disabledDate?: (date: Dayjs) => boolean;
  /** 是否选择时间，默认false */
  showTime?: boolean;
}

const weeks = ['一', '二', '三', '四', '五', '六', '日'];

const Calendar = ({
  onChange,
  value,
  disabled,
  staticed,
  onBlur,
  clearable = false,
  placeholder,
  className,
  disabledDate,
  minDate,
  maxDate,
  mode = 'day',
}: CalendarProps) => {
  const values = useMemo(() => {
    if (!value) {
      return [];
    }
    if (Array.isArray(value)) {
      return value;
    }
    return [value];
  }, [value]);
  /** 当前选中的年月 */
  const [yearMonth, setYearMonth] = useState(dayjs());

  const state = useReactive({
    /** 临时用，给range mode使用 */
    tempRange: [] as string[],
    /** 切换 日、年、月选择器界面 */
    exchangeMode: 'default' as 'default' | 'year' | 'month',
  });
  // console.log('tempRange', tempRange);
  // console.log('values', values);

  const prevBig = () => {
    setYearMonth(yearMonth.subtract(1, 'year'));
  };
  const prev = () => {
    setYearMonth(yearMonth.subtract(1, 'month'));
  };
  const next = () => {
    setYearMonth(yearMonth.add(1, 'month'));
  };
  const nextBig = () => {
    setYearMonth(yearMonth.add(1, 'year'));
  };

  const items = useMemo(() => {
    const list: CalendarRenderItem[] = [];
    const daysInMonth = yearMonth.daysInMonth();
    const value0 = values[0];
    const value1 = values[1];
    const dayOfWeek = yearMonth.startOf('month').day(); // 周二 = 2
    let date = yearMonth;
    for (let i = 0; i < daysInMonth; i++) {
      let itemDisabled = false;
      let itemActive = false;
      let itemActiveFirst = false;
      let itemActiveLast = false;
      date = yearMonth.startOf('month').add(i, 'day');
      if (minDate && date.isBefore(minDate)) {
        itemDisabled = true;
      }
      if (maxDate && date.isAfter(maxDate)) {
        itemDisabled = true;
      }
      if (disabledDate && disabledDate(date)) {
        itemDisabled = true;
      }
      if (mode == 'day') {
        if (value0 && dayjs(value0).format('YYYY-MM-DD') === date.format('YYYY-MM-DD')) {
          itemActive = true;
        }
      } else if (mode == 'range') {
        if (state.tempRange.length) {
          if (state.tempRange.length == 1) {
            if (state.tempRange[0] && dayjs(state.tempRange[0]).format('YYYY-MM-DD') === date.format('YYYY-MM-DD')) {
              itemActive = true;
              itemActiveFirst = true;
            }
          } else {
            const data = isInTimeRange(date, state.tempRange[0], state.tempRange[1]);
            itemActive = data.active;
            itemActiveFirst = data.activeFirst;
            itemActiveLast = data.activeEnd;
          }
        } else {
          const data = isInTimeRange(date, value0, value1);
          itemActive = data.active;
          itemActiveFirst = data.activeFirst;
          itemActiveLast = data.activeEnd;
        }
      }
      list.push({
        text: (i + 1).toString(),
        value: date.format('YYYY-MM-DD'),
        disabled: itemDisabled,
        active: itemActive,
        activeFirst: itemActiveFirst,
        activeLast: itemActiveLast,
      });
    }
    for (let i = 0; i < dayOfWeek - 1; i++) {
      list.unshift({
        text: '',
        value: '',
        disabled: true,
        active: false,
        activeFirst: false,
        activeLast: false,
      });
    }
    // console.log('list', list);
    return list;
  }, [disabledDate, maxDate, minDate, mode, state.tempRange, values, yearMonth]);

  const onClickItem = (item: CalendarRenderItem) => {
    if (mode === 'day') {
      onChange?.(item.value);
    } else if (mode === 'range') {
      if (!state.tempRange.length) {
        state.tempRange = [item.value];
      } else if (state.tempRange.length === 1) {
        let newList: string[] = [];
        const pre = dayjs(state.tempRange[0]);
        if (pre.startOf('day').valueOf() === dayjs(item.value).startOf('day').valueOf()) {
          newList = [item.value, item.value];
        } else {
          if (pre.startOf('day').valueOf() > dayjs(item.value).startOf('day').valueOf()) {
            newList = [item.value, state.tempRange[0]];
          } else {
            newList = [state.tempRange[0], item.value];
          }
        }
        state.tempRange = newList;
        onChange?.(newList);
      } else if (state.tempRange.length === 2) {
        state.tempRange = [];
        onChange?.([]);
      }
    }
  };

  useEffect(() => {
    // 根据value显示第一次的默认位置
    setYearMonth(dayjs(values[0]));
  }, [values]);

  if (staticed) {
    return <View className='pd-calendar--static'>{value}</View>;
  }
  if (state.exchangeMode === 'year') {
    return (
      <YearView
        value={yearMonth.format('YYYY-MM')}
        mode='day'
        onChange={v => {
          setYearMonth(yearMonth.set('year', Number(v as string)));
          state.exchangeMode = 'default';
        }}
      />
    );
  } else if (state.exchangeMode === 'month') {
    return (
      <MonthView
        value={yearMonth.format('YYYY-MM')}
        mode='day'
        onChange={v => {
          setYearMonth(dayjs(v as string));
          state.exchangeMode = 'default';
        }}
      />
    );
  }
  const headerStr = yearMonth.format('YYYY年MM月');
  return (
    <View className={classNames({ 'pd-calendar': true, 'pd-calendar--disabled': disabled }, className)}>
      <View className='pd-calendar__head'>
        <Icon name='left-double-arrow' className='pd-calendar__head__icon' onClick={prevBig} style={{ marginRight: pxTransform(10) }} />
        <Icon name='left' className='pd-calendar__head__icon' onClick={prev} />
        <View className='pd-calendar__head__center'>
          <TextClickable
            onClick={() => {
              state.exchangeMode = 'year';
            }}>
            {yearMonth.format('YYYY年')}
          </TextClickable>
          <TextClickable
            onClick={() => {
              state.exchangeMode = 'month';
            }}>
            {yearMonth.format('MM月')}
          </TextClickable>
        </View>
        <Icon name='right' className='pd-calendar__head__icon' onClick={next} />
        <Icon name='right-double-arrow' className='pd-calendar__head__icon' onClick={nextBig} style={{ marginLeft: pxTransform(10) }} />
      </View>
      <View className='pd-calendar__list'>
        <Grid column={7} className='pd-calendar__list'>
          {weeks.map(item => (
            <CalendarItem key={'week_' + item} disabled={true} disabledColor={false} active={false} activeFirst={false} activeLast={false}>
              {item}
            </CalendarItem>
          ))}
          {items.map((item, index) => (
            <CalendarItem
              key={headerStr + 'day_' + index}
              disabled={item.disabled}
              disabledColor={item.disabled && !!item.text}
              active={item.active}
              activeFirst={item.activeFirst}
              activeLast={item.activeLast}
              onClick={() => onClickItem(item)}>
              {item.text}
            </CalendarItem>
          ))}
        </Grid>
      </View>
    </View>
  );
};

const TextClickable = ({ children, onClick, style }: TextProps) => {
  const [hover, setHover] = useState(false);
  return (
    <Text
      className={classNames('pd-calendar__head__center__text', {
        'pd-calendar__head__center__text--hover': hover,
      })}
      onTouchStart={() => setHover(true)}
      onTouchEnd={() => setHover(false)}
      onTouchMove={() => setHover(false)}
      onClick={onClick}
      style={style}>
      {children}
    </Text>
  );
};
export default Calendar;
